package ws

import (
	"fmt"
	"github.com/gorilla/websocket"
	"github.com/zeromicro/go-zero/core/logx"
	model "go-admin/base/mongo"
	"go-admin/base/mongo/ws"
	"time"
)

type ChatRoom struct {
	Id        int64   `json:"id"`
	Name      string  `json:"name"`
	ClientIds []int64 `json:"clientIds"`
	// 是否上线
	Clients map[int64]*Client
}

func (cr *ChatRoom) AddClient(clientId int64) {
	cr.ClientIds = append(cr.ClientIds, clientId)
}
func (cr *ChatRoom) DeleteClient(clientId int64) {
	for i, id := range cr.ClientIds {
		if clientId == id {
			cr.ClientIds = append(cr.ClientIds[:i], cr.ClientIds[i+1:]...)
			break
		}
	}
}

type Client struct {
	UserId         int64 `json:"userId"`
	ChatRoomServer *ChatRoomServer
	Conn           websocket.Conn
	Send           chan Message
}

func NewChatRoom(id int64, name string, clientIds []int64) *ChatRoom {
	return &ChatRoom{
		Id:        id,
		Name:      name,
		Clients:   map[int64]*Client{},
		ClientIds: clientIds,
	}
}

func (c *Client) readMessage(crs *ChatRoomServer) {
	svcCtx := c.ChatRoomServer.svcCtx
	mongoInserter, _ := ws.NewMongoInserter(svcCtx.MessageModel)
	defer mongoInserter.Flush()
	for {
		message := Message{}
		err := c.Conn.ReadJSON(&message)
		if err != nil {
			if websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseGoingAway) {
				// 连接正常关闭或正在关闭
				fmt.Println("连接关闭:", err)
			} else {
				// 连接异常关闭
				fmt.Println("连接异常关闭:", err)
			}
			fmt.Println(err, ">>>>>")
			// 连接关闭后应该删除配置中的对应的连接信息
			crs.UnRegister <- c
			break
		}
		fmt.Println("recive: ", message)
		//marshal, _ := json.Marshal(message)
		if message.Type == GroupMessageType {
			crs.BroadcastData <- message
		} else if message.Type == SimpleMessageType {
			toId := message.SimpleMessage.ToId
			client := crs.Clients[toId]
			fmt.Println(crs.Clients)

			// 不管是否在线，都存储数据
			fromId := message.SimpleMessage.FromId
			var fromToId string
			if fromId <= toId {
				fromToId = fmt.Sprintf("%d:%d", fromId, toId)
			} else {
				fromToId = fmt.Sprintf("%d:%d", toId, fromId)
			}
			mongoInserter.Insert(model.Message{
				FromID:   message.SimpleMessage.FromId,
				ToID:     message.SimpleMessage.ToId,
				Type:     message.SimpleMessage.Type,
				Content:  message.SimpleMessage.Content,
				FromToID: fromToId,
				CreateAt: time.Now(),
				UpdateAt: time.Now(),
			})

			if client == nil {
				logx.Error("该用户不在线：UserId：", toId)
				continue
			}
			client.Send <- message
		} else if message.Type == LoginMessageType {
			//loginMessage := Message{}
			// 此处会阻塞，知道客户端有消息发送，才会继续往下走,升级协议后，此处的代码就不会继续执行了
			// 这里的读取消息只会执行一次，即第一次建立连接时，第一次读取客户端信息，相当于建立连接应该处理的事情
			//err = conn.ReadJSON(&loginMessage)
			userId := message.LoginMessage.UserId
			cc := crs.Clients[userId]
			if cc != nil {
				logx.Error("已登陆，不需要重复登录。。。")
				//todo 重复登录，目前关闭新的连接，只支持单设备连接，目前是只要一个连接不关闭，同一用户不能创建新的连接，后续心跳检测，断开连接
				c.Conn.Close()
				return
			}
			// c 在这里其实是个半成品，并没有真正注册到容器中，还缺少userid
			c.UserId = userId
			crs.Register <- c

		} else {
			logx.Error("未知消息。。。。", message)
		}

	}
}

func (c *Client) writeMessage(crs *ChatRoomServer) {

	for {
		select {
		case v := <-c.Send:
			fmt.Println("send: ", v)
			//c.Conn.WriteMessage(websocket.BinaryMessage, v)
			err := c.Conn.WriteJSON(v)
			if err != nil {
				if websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseGoingAway) {
					// 连接正常关闭或正在关闭
					fmt.Println("连接关闭:", err)
				} else {
					// 连接异常关闭
					fmt.Println("连接异常关闭:", err)
				}
				fmt.Println(err, ">>>>>")
				// 连接关闭后应该删除配置中的对应的连接信息
				crs.UnRegister <- c
				break
			}
		default:
			//fmt.Println("----")
		}
	}
}
